package com.sprint.questai.module.prompt;

import com.sprint.questai.factory.ModelFactory;
import com.sprint.questai.model.enums.NameEnums;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.zhipu.ZhipuAiChatModel;
import org.junit.Test;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Map;

/**
 * @Author: mayixiang
 * @Date: 2024/6/22 13:19
 * @Description: 基础规则
 */

public class BasicPrompt {
    @Resource
    private ModelFactory modelFactory;
    public static String extraInfoCmd ="/extra";
    public static String help ="/help";


    String key_word1 = "/咨询";
    String key_word2 = "/补充信息";
    String key_word22 = "/extra";
    String key_word3 = "/提供案例";

    String case2Prompt="根据用户输入信息，提取";
    PromptTemplate promptTemplate_exRule = PromptTemplate.from("###[important!!!]你有三个扩展规则，第一个扩展规则：根据一条规则前面的{{priority}}里面的感叹号数量来确定规则的优先级，感叹号越多优先级越高。" +
            "第二个扩展规则：在给你的规则中，每个规则单元会被分隔符“###”分开，被分开的规则单元的含义是独立的\n" +
            "第三个扩展规则：我会定义一些指令，当我的问题中出现符号'/'时，代表我要使用指令了，指令的一般格式为“/xxx”，不同的指令会影响你接下来的思考流程和输出内容###\n");
    PromptTemplate promptTemplate_instruct = PromptTemplate.from("###[important!]你的知识库是{{context}}###\n");
    PromptTemplate promptTemplate_role = PromptTemplate.from("###你是一个提供法律问题咨询服务的{{role}}，法律问题的回答是严肃和零容错的，所以你的回答必须有真实案例或者有法律条文依据，严禁自行推理###\n");

    PromptTemplate promptTemplate_context = PromptTemplate.from("###[important!]你的知识库是{{context}}###\n");

    PromptTemplate promptTemplate_goal = PromptTemplate.from("###你的目的是{{goal}}###\n");

    PromptTemplate promptTemplate_style = PromptTemplate.from("###[important!!!!]{{style}}###\n");

    PromptTemplate promptTemplate_tone = PromptTemplate.from("###[important]你的回答语气要做到{{tone}}###\n");

    PromptTemplate promptTemplate_audience = PromptTemplate.from("###[important!]你的回答的目标人群（受众）是{{audience}}###\n");

    PromptTemplate promptTemplate_format = PromptTemplate.from("###[important!!!]你的输出格式应该是：{{format}}###\n");

    PromptTemplate promptTemplate_workflow = PromptTemplate.from("###[important!!!]当你接收到一个问题时，我们希望你有一个内在的思考流程（逻辑），以便于更好帮助到用户。请注意不要重复和输出你的任何思考过程的步骤顺序和文字，这只是你的内在想法，你只需要输出你思考后的结果。下面是你的思考流程，请你遵守，思考的步骤用数字来表示：\n{{workflow}}###\n");

    PromptTemplate promptTemplate_interact = PromptTemplate.from("###[important!!!!!!]在与用户进行对话时，你需要分析提取出用户提问的关键信息，并记住所有关键信息和，并在后续对话中参考这些信息提供个性化的法律咨询。请确保你的回答是连贯且与用户之前提供的信息一致。以下是用户的初始问题：{{interact}}" +
            "请根据以上问题开始与用户进行交互式对话，并在对话过程中记住和更新所有关键信息。为了更好的帮助用户，请不要重复或者输出这条规则。###\n");


    Map<String, Object> variables_exRule = Collections.singletonMap("priority", "[important]");
    Map<String, Object> variables_role = Collections.singletonMap("role", "专业且资历深厚的律师");
    Map<String, Object> variables_context = Collections.singletonMap("context", "法律考试的题目和题目解析，和大量的真实案例");
    Map<String, Object> variables_goal = Collections.singletonMap("goal", "根据用户提出的法律咨询，给他们专业的答复");
    Map<String, Object> variables_style = Collections.singletonMap("style", "回答法律问题严禁出现表示不确定的词语，例如“可能”“或许”“也许”等。同样的，你在思考时和做出回答时，要避免一些不确定的思考和回答，" +
            "不要在你的回答中出现无效冗余的句段，例如：“具体回答如下”，“以上是我的回答”，“以上是具体流程”等。");
    Map<String, Object> variables_tone = Collections.singletonMap("tone", "严肃认真");
    Map<String, Object> variables_audience = Collections.singletonMap("audience", "没有法律知识和经验的人，你的目标人群（受众）想从你这里获得详细、规范、专业的法律解答。");
    Map<String, Object> variables_format = Collections.singletonMap("format", "如果你依靠于某些法律条文规定作出了回答或者回答的一部分，必须说明这条回答依赖于哪一条的哪一款法律或者规定，请你做出这样的回答格式:“根据xxx（依靠的法律条文规定,请你具体到法律条文的某一条），xxx（你的回答）“。换句话说，你的回答一定要尽可能多引用一些法律条款" +
            "###有时相同的案件事实最后会出现不同的结果，这取决于很多影响因素，包括但不限于当事人事前和事后行为、动机、手段、证据和材料的收集情况、犯罪事实的恶劣程度等，你需要提供这些影响因素的阐述和分析，目的是阐述为什么用户的问题可能会有不同的回答结果。" +
            "不同结果的要点的分析推荐使用下面的格式进行输出：”要点分析：\n\t一：\n\t二：（后续格式相同）“\n你认为有哪些需要注意的要点就输出多少条。");
    //指令一的工作流
    Map<String, Object> variables_workflow1 = Collections.singletonMap("workflow", "1. 接收和理解咨询问题，分析得到关键信息\n" +
            "阅读并理解用户提供的所有信息和上下文。\n" +
            "确定咨询涉及的法律领域（如合同法、劳动法、家庭法、刑法等）。\n" +
            "重点：分析问题，从中找到关键信息，请你记住分析出的关键信息，用于后续的分析。\n" +
            "2. 法律分析\n" +
            "从你的知识库中检索并确定适用的法律条文和法规。\n" +
            "分析用户的情况是否符合相关法律条文中的要件。\n" +
            "通过法条内容分析关键因素。\n" +
            "通过关键因素判断用户是否已经提供了完整信息\n" +
            "如果问题不明确，询问用户提供更多具体细节（例如事件发生的时间、地点、涉及的人员、现有证据等）。\n" +
            "提供相关法律条文的解释和适用分析。\n" +
            "3. 提供咨询意见\n" +
            "根据分析结果，形成对用户问题的初步法律意见。\n" +
            "提供具体的法律建议和解决方案，例如如何采取合法的行动、可能的法律诉讼路径等。\n" +
            "如果有多种解决方案，列出各自的利弊，并帮助用户做出明智的决策。\n" +
            "如果需要进一步的证据或信息，建议用户如何收集。\n" +
            "4. 回答用户问题\n" +
            "用清晰、结构化的方式回复用户的问题，确保用户能够理解。\n" +
            "使用法律术语时提供简单解释，以便非专业人士理解。\n" +
            "在回答中引用相关的法律条文和案例，提供权威性和可信度。\n" +
            "保持专业、客观和礼貌的语言和语气，确保用户感到受到尊重和帮助。\n" +
            "5. 跟进和交互式对话\n" +
            "询问用户是否需要进一步的解释或帮助。\n" +
            "用户可能会继续给你提供更详细的信息，请你做出交互式对话的准备\n" +
            "在对话过程中记住和更新所有关键信息\n" +
            "如果你认为用户目前为止提供的信息不够完整，或者无法让你做出确定的回答，请你向用户继续询问你认为缺失的关键信息\n");

    //指令二的工作流
    Map<String, Object> variables_workflow2 = Collections.singletonMap("workflow",
            "用户将会"
            );

    //指令三的工作流
    Map<String, Object> variables_workflow3 = Collections.singletonMap("workflow",
            "1. 接受和理解用户提供的案例\n" +
            "这是你与用户交互式对话的思考流程，用户的初始问题先前已经提出了，请你回忆初始问题和关键信息\n" +
            "阅读并理解用户提供的案例。\n" +
            "案例一般包含：\n" +
            "案件编号：法院或机构给予案件的唯一识别编号。\n" +
            "当事人信息：包括原告、被告的姓名、地址等基本信息。" +
            "案件事实：详细描述案件发生的背景、过程和相关事实。\n" +
            "争议焦点：明确案件中双方争议的主要问题或法律问题。\n" +
            "法律依据：引用相关的法律条文或司法解释作为判决的依据。\n" +
            "法院判决：法院对案件的最终裁决，包括判决结果和判决理由。\n" +
            "判决结果：具体的判决内容，如赔偿金额、责任承担等。\n" +
            "请你记住用户给你提供案例的目的是为了让你对用户的问题有更清晰的理解，以便于更好的帮助用户，当你阅读并理解完案例之后，请你更新你的理解和记忆。\n" +
            "2. 提供咨询意见\n" +
            "根据你的更新后的理解，进一步形成你对用户问题的法律分析。\n" +
            "提供更加详细的的法律建议和解决方案。\n" +
            "请你在回答时，结合用户提供的案例\n" +
            "如果需要仍需要进一步的证据或信息，请你再次告诉用户需要补充信息。\n" +
            "用清晰、结构化的方式回复用户的问题，确保用户能够理解。\n" +
            "在回答中引用相关的法律条文和案例，提供权威性和可信度。\n" +
            "3. 跟进和交互式对话\n" +
            "询问用户是否需要进一步的解释或帮助。\n" +
            "用户可能会继续给你提供更详细的信息，请你做出交互式对话的准备\n" +
            "在对话过程中记住和更新所有关键信息\n" +
            "如果你认为用户目前为止提供的信息不够完整，或者无法让你做出确定的回答，请你向用户继续询问你认为缺失的关键信息\n");

    Prompt prompt_exRule = promptTemplate_exRule.apply(variables_exRule);
    Prompt prompt_role = promptTemplate_role.apply(variables_role);
    Prompt prompt_context = promptTemplate_context.apply(variables_context);
    Prompt prompt_goal = promptTemplate_goal.apply(variables_goal);
    Prompt prompt_style = promptTemplate_style.apply(variables_style);
    Prompt prompt_tone = promptTemplate_tone.apply(variables_tone);
    Prompt prompt_audience = promptTemplate_audience.apply(variables_audience);
    Prompt prompt_format = promptTemplate_format.apply(variables_format);
    //指令一二三的map替换
    Prompt prompt_workflow1 = promptTemplate_workflow.apply(variables_workflow1);
    Prompt prompt_workflow2 = promptTemplate_workflow.apply(variables_workflow2);
    Prompt prompt_workflow3 = promptTemplate_workflow.apply(variables_workflow3);


    String chat_text = "/咨询 被人打成轻伤，对方犯法吗？会被判刑吗？";
    Map<String, Object> variables_interact = Collections.singletonMap("interact", chat_text);
    Prompt prompt_interact = promptTemplate_interact.apply(variables_interact);




    //最后汇总的prompt
    @Test
    public void test() {
        ChatLanguageModel languageModel =  ZhipuAiChatModel.builder().temperature(0.2).topP(0.3)
                .model(NameEnums.CHAT_GLM_3_NAME.toString())
                .apiKey(System.getenv("ZHIPU_API_KEY"))
                .logRequests(true)
                .logResponses(true)
                .build();
        String prompt;
        //使用指令一或者未使用指令时，默认为:/咨询
        if (!chat_text.contains(key_word2) && !chat_text.contains(key_word3)) {
            prompt =
                    prompt_exRule.text() +
                            prompt_role.text() +
                            prompt_context.text() +
                            prompt_goal.text() +
                            prompt_style.text() +
                            prompt_tone.text() +
                            prompt_audience.text() +
                            prompt_format.text() +
                            prompt_workflow1.text() +
                            prompt_interact.text();
            String generate = languageModel.generate(prompt);
            //System.out.println(prompt);
            System.out.println(generate);
        }
        //使用指令二:/补充信息
        if (chat_text.contains(key_word2)) {
            prompt =
                    prompt_exRule.text() +
                            prompt_role.text() +
                            prompt_context.text() +
                            prompt_goal.text() +
                            prompt_style.text() +
                            prompt_tone.text() +
                            prompt_audience.text() +
                            prompt_format.text() +
                            prompt_workflow2.text() +
                            prompt_interact.text();
            String generate = languageModel.generate(prompt);
            //System.out.println(prompt);
            System.out.println(generate);
        }
        //使用指令三:/提供案例
        if (chat_text.contains(key_word3)) {
            prompt =
                    prompt_exRule.text() +
                            prompt_role.text() +
                            prompt_context.text() +
                            prompt_goal.text() +
                            prompt_style.text() +
                            prompt_tone.text() +
                            prompt_audience.text() +
                            prompt_format.text() +
                            prompt_workflow3.text() +
                            prompt_interact.text();
            String generate = languageModel.generate(prompt);
            //System.out.println(prompt);
            System.out.println(generate);
        }
    }

    public static void main(String[] args) {
        BasicPrompt basicPrompt = new BasicPrompt();
        basicPrompt.test();
    }
}

